
package hidra.metaheuristics.dfmopso;

import hidra.experiments.Paramenters;
import hidra.jmetal.core.*;
import hidra.qualityIndicator.QualityIndicator;

import java.io.IOException;

import jmetal.operators.mutation.Mutation;
import jmetal.operators.mutation.MutationFactory;
import jmetal.problems.*;
import jmetal.problems.ZDT.*;
import jmetal.problems.adaboost.AdaBoostProblem;
import jmetal.problems.adaboost.Adaboost;
import jmetal.problems.adaboost.Config;
import jmetal.problems.WFG.*;
import jmetal.problems.DTLZ.*;
import jmetal.problems.LZ09.* ;
import jmetal.util.Configuration;
import jmetal.util.JMException ;

import java.util.HashMap;
import java.util.logging.FileHandler;
import java.util.logging.Logger;

import DataReader.DataReader;

/**
 * This class executes the SMPSO algorithm described in:
 * A.J. Nebro, J.J. Durillo, J. Garcia-Nieto, C.A. Coello Coello, F. Luna and E. Alba
 * "SMPSO: A New PSO-based Metaheuristic for Multi-objective Optimization". 
 * IEEE Symposium on Computational Intelligence in Multicriteria Decision-Making 
 * (MCDM 2009), pp: 66-73. March 2009
 */
public class DFMOPSO_main {
  public static Logger      logger_ ;      // Logger object
  public static FileHandler fileHandler_ ; // FileHandler object

  /**
   * @param args Command line arguments. The first (optional) argument specifies 
   *             the problem to solve.
   * @throws JMException 
   * @throws IOException 
   * @throws SecurityException 
   * Usage: three options
   *      - jmetal.metaheuristics.mocell.MOCell_main
   *      - jmetal.metaheuristics.mocell.MOCell_main problemName
   *      - jmetal.metaheuristics.mocell.MOCell_main problemName ParetoFrontFile
   */
  public static void main(String [] args) throws JMException, IOException, ClassNotFoundException {
    Problem   problem   ;  // The problem to solve
    Algorithm algorithm ;  // The algorithm to use
    Mutation  mutation  ;  // "Turbulence" operator
    
    QualityIndicator indicators ; // Object to get quality indicators
        
    HashMap  parameters ; // Operator parameters

    // Logger object and file to store log messages
    logger_      = Configuration.logger_ ;
    fileHandler_ = new FileHandler("DFMOPSO_main.log"); 
    logger_.addHandler(fileHandler_) ;
    
    indicators = null ;
 if (args.length == 1) {
      Object [] params = {"Real"};
      problem = (new ProblemFactory()).getProblem(args[0],params);
    } // if
    else if (args.length == 2) {
      Object [] params = {"Real"};
      problem = (new ProblemFactory()).getProblem(args[0],params);
      indicators = new QualityIndicator(problem, args[1]) ;
    } // if
    else { // Default problem
      Paramenters.NOBJ = 2;
      //numero de variaveis = numero de classificadores (i) * quantidade
      //parametros por classificadores
      
      
    } // else
 	SolutionSet fullPopulation = new SolutionSet((21-5)*30);
 	for(int cascadeLength = 5; cascadeLength < 21; cascadeLength++)
 	{
		System.out.println("-----------------------\nTamanho da cascata: " + cascadeLength);
		 int numberOfVariables = cascadeLength * Config.NUMBER_OF_PARAMETERS;;
		 problem = new AdaBoostProblem("Real", numberOfVariables, 2);
		 indicators = new QualityIndicator(problem, "resource/paretoFronts/DTLZ1.2D.pf");
	 
	 
		 algorithm = new DFMOPSO(problem) ;	
	    
		// Algorithm parameters
		 algorithm.setInputParameter("swarmSize",100);
		 algorithm.setInputParameter("archiveSize",100);
		 algorithm.setInputParameter("maxIterations",1000);
		 algorithm.setInputParameter("indicators", indicators);
		
		 parameters = new HashMap() ;
		 parameters.put("probability", 1.0/problem.getNumberOfVariables()) ;
		 parameters.put("distributionIndex", 20.0) ;
		 mutation = MutationFactory.getMutationOperator("PolynomialMutation", parameters);                    
		
		 algorithm.addOperator("mutation", mutation);
		
		
		// Execute the Algorithm 
		 long initTime = System.currentTimeMillis();
		
		 SolutionSet population = algorithm.execute();
		 for(int i = 0; i < population.size(); i++)
		 {
			 fullPopulation.add(population.get(i));
		 }
		 long estimatedTime = System.currentTimeMillis() - initTime;
 	}
 	//iniciando processo de prunning
 	DataReader.saveSolutionSet(fullPopulation);
 	System.out.println("Iniciando processo de prunning");
 	DataReader.pruneAndSavePareto(fullPopulation);

    
    // Result messages 
    /*
    logger_.info("Total execution time: "+estimatedTime + "ms");
    logger_.info("Objectives values have been writen to file FUN");
    */
    
    
    //logger_.info("Variables values have been writen to file VAR");
    /*
    if (indicators != null) {
      logger_.info("Quality indicators") ;
      logger_.info("Hypervolume: " + indicators.getHypervolume(population)) ;
      logger_.info("GD         : " + indicators.getGD(population)) ;
      logger_.info("IGD        : " + indicators.getIGD(population)) ;
      logger_.info("Spread     : " + indicators.getSpread(population)) ;
      logger_.info("Epsilon    : " + indicators.getEpsilon(population)) ;
    } */// if     

  } //main
} // SMPSO_main
